package wangjg.sso;

import java.net.URI;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import wangjg.security.core.LoginModule;
import wangjg.security.http.HttpContext;
import wangjg.sso.util.CookieUtil;


public class SsoLoginModule implements LoginModule {
	private static final String COOKIE_SESSIONID = "JSESSIONID";
	private static final String COOKIE_TOKEN = "_token_";
	private static final String COOKIE_SERVID = "_servid_";
	private RemoteLogin remoteLogin = new RemoteLogin();

	private Config config = Config.instance;
	private String thisServerid;
	private String[] domains;
	private HashMap<Integer, URI> loginUris;
	private String userSessionKey;

	public SsoLoginModule() {
		domains = config.getSetting("sso.crossed.domains").split(",");
	}

	public String getUserSessionKey() {
		return userSessionKey;
	}

	public void setUserSessionKey(String userSessionKey) {
		this.userSessionKey = userSessionKey;
	}

	private HashMap<Integer, URI> getLoginUris() {
		if (loginUris == null) {
			synchronized (this) {
				if (loginUris == null) {
					this._getLoginUris();
				}
			}
		}
		return loginUris;
	}

	private void _getLoginUris() {
		Properties settings = Config.instance.getSettings();
		for (Map.Entry entry : settings.entrySet()) {
			String key = (String) entry.getKey();
			String val = (String) entry.getValue();
			if (key.startsWith("sso.login.uris.")) {
				int pos1 = key.lastIndexOf('.');
				String id = key.substring(pos1 + 1);
				try {
					URI uri = new URI(val);
					this.loginUris.put(Integer.parseInt(id), uri);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}
	}

	/**
	 * 从配置文件加载服务器列表,根据servid选择之
	 * 
	 * @param servid
	 * @return
	 */
	private String getUri(int servid) {
		String uri = Config.instance.getSetting("sso.login.uris." + servid);
		return uri;
	}

	public Object login() {
		HttpServletRequest request = HttpContext.getRequest();
		Object user = request.getSession().getAttribute(userSessionKey);
		if (user == null) {
			try {
				user = this.loginByRemote();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return user;
	}

	/**
	 * 登陆成功之后调用,设置cookie的作用域
	 */
	public void setCrossedDomain() {
		HttpServletRequest request = HttpContext.getRequest();
		HttpServletResponse response = HttpContext.getResponse();
		Cookie sessionCookie = CookieUtil.findCookie(request, COOKIE_SESSIONID);
		Cookie servidCookie = CookieUtil.findCookie(request, COOKIE_SERVID);

		/*p3p*/
		response.addHeader("P3P", "CP=CURa ADMa DEVa PSAo PSDo OUR BUS UNI PUR INT DEM STA PRE COM NAV OTC NOI DSP COR");
		/*
		 * 设置作用域
		 */
		for (String domain : domains) {
			if (sessionCookie.getDomain().equals(domain)) {
				continue;
			}
			Cookie cookie = (Cookie) sessionCookie.clone();
			cookie.setDomain(domain);
			response.addCookie(cookie);
		}

		/*
		 * 读取配置文件中的域名列表,发送sesion-cookie,每个域都生成,在这些域间共享 登陆成功后调用
		 */
		if (servidCookie == null) {
			servidCookie = new Cookie(COOKIE_SERVID, thisServerid);
		}
		if (!thisServerid.equals(servidCookie.getValue())) {
			servidCookie.setValue(thisServerid);
			response.addCookie(servidCookie);
		}
	}

	private Object loginByRemote() throws Exception {
		HttpServletRequest request = HttpContext.getRequest();
		HttpServletResponse response = HttpContext.getResponse();
		Cookie servidCookie = CookieUtil.findCookie(request, COOKIE_SERVID);
		if (servidCookie == null) {
			return null;
		}
		if (thisServerid.equals(servidCookie.getValue())) {
			return null;
		}
		int servid = Integer.parseInt(servidCookie.getValue());
		Cookie cookie2 = CookieUtil.findCookie(request, COOKIE_TOKEN);
		String token = cookie2.getValue();
		// 远程方法调用，然后返回userid，然后本地加载用户信息
		String uri = this.getUri(servid);
		String userid = (String) remoteLogin.login(uri, token);
		if (userid == null) {
			return null;
		}
		return loadUserInfo(userid);
	}

	private Object loadUserInfo(String userid) {
		return null;
	}

	public Object logout() {
		HttpServletRequest request = HttpContext.getRequest();
		Object user = request.getSession().getAttribute(userSessionKey);
		request.getSession().removeAttribute(userSessionKey);
		return user;
	}

	public static void main(String args[]) throws Exception {
		URI uri = new URI("http://www.xxx.com");
		System.out.println(uri.getHost());
	}

}
